#include "ZFrameworks.h"
#include "../Tools/ZLogManager.h"
#include "../Render/RenderSystem.h"
#include "../Tools/XmlParser.h"

GLOBAL_NAMESPACE_BEGIN

template<> ZFrameworks* Singleton<ZFrameworks>::singleton_ = 0;

ZFrameworks::ZFrameworks(const std::string& configFileName, const std::string& logFileName)
    : logFileName_(logFileName)
    , configFileName_(configFileName)
{

}

ZFrameworks::~ZFrameworks()
{
    destroy();
}

void ZFrameworks::destroy()
{
}

void ZFrameworks::init()
{
    logManager_.reset(new LogManager);
    appManager_.reset(new AppManager);
    renderSystem_.reset(new RenderSystem);
    dataManager_.reset(new DataManager);
    configManager_.reset(new ConfigManager);
    imageFeatureManager_.reset(new ImageFeatureManager);
#ifdef RENDER_OPENGL
    shaderSystem_.reset(new ShaderSystem);
#endif

    LogManager::getSingletonPtr()->init();
    AppManager::getSingletonPtr()->init();
    RenderSystem::getSingletonPtr()->init();
    DataManager::getSingletonPtr()->init();
#ifdef RENDER_OPENGL
    ShaderSystem::getSingletonPtr()->init();
#endif

    parserConfigFile();
    if (!logFileName_.empty())
        LogManager::getSingletonPtr()->createLog(std::string("Default"), logFileName_, true);
}


void ZFrameworks::parserConfigFile()
{
    //FileTools::XmlParser xmlParser(configFileName_.c_str());
    tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument;
    if (doc->LoadFile(configFileName_.c_str()) != tinyxml2::XML_NO_ERROR)
    {
        delete doc;
        return;
    }
    
    tinyxml2::XMLElement* node = doc->FirstChildElement();  // root
    while (node)
    {
        if (strcmp(node->Name(), "Materials")==0)
        {
            tinyxml2::XMLElement* elem = node->FirstChildElement();
            while (elem)
            {
                if (strcmp(elem->Name(), "Log")==0)
                {
                    tinyxml2::XMLElement* elemChild = elem->FirstChildElement("LogFile");
                    while(elemChild)
                    {
                        std::string type(elemChild->FirstChildElement("type")->GetText());
                        std::string name(elemChild->FirstChildElement("name")->GetText());
                        std::string srcFile(elemChild->FirstChildElement("srcFile")->GetText());
                        logFileName_ = srcFile;

                        LogManager::getSingletonPtr()->createLog(name, logFileName_);
                        elemChild = elemChild->NextSiblingElement("LogFile");
                    }
                }
                else if (strcmp(elem->Value(), "ini")==0)
                {
                    configIniFileName_ = std::string(elem->FirstChildElement("src")->GetText());
                    if (!configIniFileName_.empty())
                    {
                        ConfigManager::getSingletonPtr()->init(configIniFileName_);
                    }
                }
#ifdef RENDER_OPENGL
                else if (strcmp(elem->Name(), "Render")==0)
                {
                    tinyxml2::XMLElement* elemChild = elem->FirstChildElement("Shader");
                    while (elemChild)
                    {
                        std::string type(elemChild->FirstChildElement("type")->GetText());
                        std::string name(elemChild->FirstChildElement("name")->GetText());
                        std::string srcF(elemChild->FirstChildElement("srcFile")->GetText());

                        ShaderSystem::getSingletonPtr()->createShader(type.c_str(), name.c_str(), srcF.c_str());
                        elemChild = elemChild->NextSiblingElement("Shader");
                    }
                }
#endif
                elem = elem->NextSiblingElement();                
            }
        }
        node = node->NextSiblingElement();
    }
}

GLOBAL_NAMESPACE_END